package com.heima.wemedia.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.AutoScanService;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.thread.WmUserThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
@Slf4j
@Transactional
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private AutoScanService autoScanService;

    @Override
    public ResponseResult newsList(WmNewsPageReqDto dto) {
        if (dto == null) {
            return new PageResponseResult(0, 0, 0);
        }
        Integer size = dto.getSize();
        Integer currentPage = dto.getPage();

        Short status = dto.getStatus();
        Date beginPubDate = dto.getBeginPubDate();
        Date endPubDate = dto.getEndPubDate();
        Integer channelId = dto.getChannelId();
        String keyword = dto.getKeyword();


        //构造查询条件
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(status != null, WmNews::getStatus, status);
        wrapper.eq(channelId != null, WmNews::getChannelId, channelId);
        wrapper.like(keyword != null, WmNews::getTitle, keyword);
        wrapper.between(beginPubDate != null && endPubDate != null, WmNews::getPublishTime, beginPubDate, endPubDate);
        wrapper.eq(WmNews::getUserId, WmUserThreadLocal.get().getId());
        //构造分页对象
        Page<WmNews> page = new Page<>(currentPage, size);

        Page<WmNews> wmNewsPageResult = wmNewsMapper.selectPage(page, wrapper);

        //封装返回前端的对象
        Long total = wmNewsPageResult.getTotal();
        PageResponseResult pageResponseResult = new PageResponseResult(currentPage, size, total.intValue());

        pageResponseResult.setData(wmNewsPageResult.getRecords());
        return pageResponseResult;
    }

    //发布文章
    @Override
    public ResponseResult submit(WmNewsDto dto) {
        //1.提取入参中的参数 插入到WmNews表中
        WmNews wmNews = WMNewSDtoToWmNews(dto);
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        int insertResult = wmNewsMapper.insert(wmNews);
        if (insertResult < 1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        //2.判断文章状态 0草稿 1提交
        if (dto.getStatus() == 0) {
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }
        //3.提取内容图
        String content = dto.getContent();
        List<String> contentImages = getmaterialImages(content);
        //4.提取封面图
        Short type = dto.getType();
        List<String> imagesList = addImages(contentImages, type);
        //插入到WMNew表中 并更新
        if (CollectionUtils.isEmpty(imagesList)) {
            String images = StringUtils.join(imagesList, ",");
            wmNews.setImages(images);
            wmNewsMapper.updateById(wmNews);
        }
        //5.插入素材表和素材关系表
        Integer newsId = wmNews.getId();
        Boolean aBoolean = addWmMaterial(contentImages, 0, newsId);
        if (!aBoolean) {
            throw new RuntimeException("内容图添加失败");
        }
        Boolean aBoolean1 = addWmMaterial(imagesList, 1, newsId);
        if (!aBoolean1) {
            throw new RuntimeException("封面图添加失败");
        }
        //6.调用自动审核方法
        try {
            autoScanService.AutoScanWmNews(newsId.longValue());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

    }

    //补齐WmNews对象
    @Transactional
    public WmNews WMNewSDtoToWmNews(WmNewsDto dto) {
        //判空
        if (dto == null) {
            log.warn("dto为空!");
            return null;
        }
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto, wmNews);
        //补齐剩余参数
        wmNews.setUserId(WmUserThreadLocal.get().getId());
        wmNews.setCreatedTime(new Date());
        wmNews.setEnable((short) 1);
        //将集合转为每个元素用,分隔的字符串StringUtils.join
        List<String> images = dto.getImages();
        String s = StringUtils.join(images, ",");
        wmNews.setImages(s);
        //文章封面类型是自动排序 WmNews表中类型设置为null
        if (dto.getType() == -1) {
            wmNews.setType(null);
        }
        return wmNews;
    }

    //提取文章内容中的图片
    @Transactional
    public List<String> getmaterialImages(String content) {
        List<String> contentImages = new ArrayList<>();
        //将content转为map类型的集合
        List<Map> maps = JSON.parseArray(content, Map.class);
        //判空
        if (CollectionUtils.isEmpty(maps)) {
            log.warn("文章内容为空!");
            return null;
        }

        //遍历集合 找到type=image的数据 将value添加到集合中
        for (Map map : maps) {
            if (CollectionUtils.isEmpty(map)) {
                continue;
            }
            Object type = map.get("type");
            if ("image".equals(map)) {
                String value = (String) map.get("value");
                contentImages.add(value);
            }
        }
        return contentImages;
    }

    //自动布局插入封面图(从内容中获取图片填充到封面图上)
    @Transactional
    public List<String> addImages(List<String> contentImages, Short type) {
        List<String> imagesList = new ArrayList<>();
        if (type != -1) {
            return null;
        }
        int size = contentImages.size();
        //内容图片大于等于3张 封面图片使用3张
        if (size >= 3) {
            imagesList.addAll(contentImages.subList(0, 2));
            return imagesList;
        } else if (size == 0) {
            //内容没有图片直接返回
            return imagesList;
        } else {
            //有1张用1张 2张用两张
            imagesList = contentImages;
        }
        return imagesList;
    }

    //插入素材表和素材关系表
    @Transactional
    public Boolean addWmMaterial(List<String> Images, Integer type, Integer newsId) {
        //集合判空
        if (CollectionUtils.isEmpty(Images)) {
            return true;
        }

        WmMaterial wmMaterial = new WmMaterial();
        wmMaterial.setUserId(WmUserThreadLocal.get().getId());
        wmMaterial.setType((short) 0);
        wmMaterial.setIsCollection((short) 0);
        wmMaterial.setCreatedTime(new Date());

        WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
        //遍历集合添加到素材表中
        for (String image : Images) {
            //集合元素非空判断
            if (StringUtils.isEmpty(image)) {
                continue;
            }
            wmMaterial.setUrl(image);
            int insert = wmMaterialMapper.insert(wmMaterial);
            if (insert < 1) {
                throw new RuntimeException("素材添加失败");
            }
            //添加到文章素材关系表
            wmNewsMaterial.setMaterialId(wmMaterial.getId());
            wmNewsMaterial.setNewsId(newsId);
            wmNewsMaterial.setOrd((short) 1);
            wmNewsMaterial.setType(type.shortValue());

            int insert1 = wmNewsMaterialMapper.insert(wmNewsMaterial);
            if (insert1 < 1) {
                throw new RuntimeException("素材关系添加失败");
            }

        }
        return true;
    }

}
